package com.itchen.school.common.utils;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.itchen.school.common.jdkext.Action2;
import com.itchen.school.common.jdkext.Function2;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

public class SysCollectionUtils {

    public SysCollectionUtils() {}

    public static <T> boolean isEmpty(Collection<T> collection) {
        return CollectionUtils.isEmpty(collection);
    }

    public static <K, V> boolean isEmpty(Map<K, V> map) {
        return com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(map);
    }

    public static <T> boolean isEmpty(T[] collection) {
        return collection == null || collection.length == 0;
    }

    public static <T> boolean isNotEmpty(Collection<T> collection) {
        return CollectionUtils.isNotEmpty(collection);
    }

    public static <T> boolean isNotEmpty(T[] collection) {
        return collection != null && collection.length > 0;
    }

    public static <K, V> boolean isNotEmpty(Map<K, V> map) {
        return com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(map);
    }

    public static <T> void forEach(Collection<T> t, Action2<T, Integer> action) {
        int i = 0;

        for(Iterator var3 = t.iterator(); var3.hasNext(); ++i) {
            T pt = (T) var3.next();
            action.call(pt, i);
        }

    }

    public static <T> void forEachIfTrue(Collection<T> t, Function2<T, Integer, Boolean> predicate, Action2<T, Integer> action) {
        int i = 0;

        for(Iterator var4 = t.iterator(); var4.hasNext(); ++i) {
            T pt = (T) var4.next();
            if ((Boolean)predicate.get(pt, i)) {
                action.call(pt, i);
            }
        }

    }

    public static <T> void batchHandle(List<T> list, int batchSize, Consumer<List<T>> handler) {
        int start = 0;

        for(int length = list.size(); start < length; start += batchSize) {
            handler.accept((List)list.stream().skip((long)start).limit((long)batchSize).collect(Collectors.toList()));
        }

    }

    public static <T> void nullIfConsumer(List<T> src, Consumer<List<T>> notNullConsumer) {
        nullIfConsumer(src, notNullConsumer, (Consumer)null);
    }

    public static <T> void nullIfConsumer(List<T> src, Consumer<List<T>> notNullConsumer, Consumer<List<T>> nullConsumer) {
        if (!isEmpty((Collection)src)) {
            if (notNullConsumer != null) {
                notNullConsumer.accept(src);
            }

            if (nullConsumer != null) {
                nullConsumer.accept(src);
            }

        }
    }

    public static <T> List<T> nullIfEmpty(List<T> src) {
        return com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(src) ? null : src;
    }

    public static String joinLimit(String delimiter, Collection<? extends CharSequence> collection, int limitCount, String postfix) {
        if (isEmpty(collection)) {
            return "";
        } else if (collection.size() <= limitCount) {
            return String.join(delimiter, collection);
        } else {
            String var10000 = String.join(delimiter, (Iterable)collection.stream().limit((long)limitCount).collect(Collectors.toList()));
            return var10000 + "..." + (String) Optional.ofNullable(postfix).orElse("");
        }
    }

    public static String simpleJoinLimit(Collection<? extends CharSequence> collection, int limitCount) {
        return joinLimit(",", collection, limitCount, "等" + collection.size() + "个");
    }

    public static <T> String joinLimit(String delimiter, List<T> objs, Function<T, CharSequence> fieldSelector, int limitCount, String postfix) {
        if (isEmpty((Collection)objs)) {
            return "";
        } else if (objs.size() <= limitCount) {
            return String.join(",", (Iterable)objs.stream().map(fieldSelector).collect(Collectors.toList()));
        } else {
            String var10000 = String.join(delimiter, (Iterable)objs.stream().limit((long)limitCount).map(fieldSelector).collect(Collectors.toList()));
            return var10000 + "..." + (String)Optional.ofNullable(postfix).orElse("");
        }
    }

    public static <T> String simpleJoinLimit(List<T> objs, Function<T, CharSequence> fieldSelector, int limitCount) {
        return joinLimit(",", objs, fieldSelector, limitCount, "等" + objs.size() + "个");
    }

    public static <A, B> List<A> getRepeatItems(List<A> listA, Function<A, B> compareKey) {
        Set<B> bSet = new HashSet();
        List<A> result = new ArrayList();
        forEachIfTrue(listA, (a, i) -> {
            return bSet.add(compareKey.apply(a));
        }, (a, i) -> {
            result.add(a);
        });
        return result;
    }

    @SafeVarargs
    public static <T> List<T> sorted(Collection<T> src, Comparator<T>... comparators) {
        Comparator<T> firstComparator = comparators[0];
        if (comparators.length > 1) {
            for(int i = 1; i < comparators.length; ++i) {
                Comparator<T> nextComparator = comparators[i];
                firstComparator = firstComparator.thenComparing(nextComparator);
            }
        }

        return (List)src.stream().sorted(firstComparator).collect(Collectors.toList());
    }

}

